package com.smartum.mpr.client.view;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.types.*;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Img;
import com.smartgwt.client.widgets.RichTextEditor;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.ValuesManager;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.UploadItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import com.smartum.mpr.client.presenter.NewsViewerPresenter;
import com.smartum.mpr.client.services.ImageService;
import com.smartum.mpr.client.services.ImageServiceAsync;
import com.smartum.mpr.client.services.NewsService;
import com.smartum.mpr.client.services.NewsServiceAsync;
import com.smartum.mpr.shared.News;

import java.util.ArrayList;
import java.util.List;

/**
 */
public class NewsViewer extends VLayout implements NewsViewerPresenter.Display {

    public static final String NO_PHOTO_NAME = "no-photobig.gif";

    Img newImage;
    TextItem title;
    TextAreaItem richTextEditor;
    ListGrid listGrid;
    final ToolStripButton add;
    final ToolStripButton update;
    final ToolStripButton delete;
    final ToolStripButton addNewNews;
    final ToolStrip actionToolStrip;
    String bufImage;

    public NewsViewer() {
        GWT.log("[CONSTRUCT COMPONENT] news");

        HLayout newsUpdateLayout = new HLayout(10);
        newsUpdateLayout.setHeight100();
        newsUpdateLayout.setWidth100();

        VLayout wrapperLayout = new VLayout();
        wrapperLayout.setBorder("1px solid gray");
        wrapperLayout.setHeight100();

        HLayout navigationLayout = new HLayout(3);
        navigationLayout.setAlign(Alignment.RIGHT);

        actionToolStrip = new ToolStrip();
        actionToolStrip.setAlign(Alignment.RIGHT);

        update = new ToolStripButton();
        update.setTitle("Update");
        update.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent clickEvent) {
                final ListGridRecord selectedRecord = listGrid.getSelectedRecord();
                final String recordId = selectedRecord.getAttribute("id");

                final MaskPanel maskPanel = new MaskPanel();
                maskPanel.show();
                final NewsServiceAsync imageServiceAsync = GWT.create(NewsService.class);
                imageServiceAsync.updateNews(recordId, bufImage, title.getValueAsString(), richTextEditor.getValueAsString(),
                        new AsyncCallback<News>() {
                            public void onFailure(Throwable caught) {
                                maskPanel.hide();
                                maskPanel.destroy();
                            }

                            public void onSuccess(News result) {
                                final RecordList dataAsRecordList = listGrid.getDataAsRecordList();
                                final Record record = dataAsRecordList.get(listGrid.getRecordIndex(selectedRecord));
                                record.setAttribute("name", result.getNewsTitle());
                                record.setAttribute("text", result.getNewsText());
                                record.setAttribute("url", result.getNewsImageUrlLittle());
                                final Canvas recordComponent = listGrid.getRecordComponent(listGrid.getRecordIndex(selectedRecord));
                                final Canvas children = recordComponent.getChildren()[1];
                                final Canvas imageChildre = recordComponent.getChildren()[0];
                                if (imageChildre != null) {
                                    ((Img) imageChildre).setSrc(result.getNewsImageUrlLittle());
                                }

                                children.setContents(result.getNewsTitle());
                                maskPanel.hide();
                                maskPanel.destroy();
                            }
                        });
            }
        });

        addNewNews = new ToolStripButton();

        addNewNews.setTitle("Add news");

        add = new ToolStripButton();

        add.setTitle("Add");
        add.setVisible(false);

        delete = new ToolStripButton();

        delete.setTitle("Delete");
        delete.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent clickEvent) {
                final ListGridRecord selectedRecord = listGrid.getSelectedRecord();
                final String recordId = selectedRecord.getAttribute("id");

                final NewsServiceAsync imageServiceAsync = GWT.create(NewsService.class);
                imageServiceAsync.delete(recordId, new AsyncCallback<List<News>>() {
                    public void onFailure(Throwable caught) {
                        //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public void onSuccess(List<News> result) {
                        updateGrid(result);
                    }
                });
            }
        }

        );

        addNewNews.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                title.setValue("");
                richTextEditor.setValue("");
                newImage.setSrc(NO_PHOTO_NAME);
                listGrid.deselectAllRecords();
                add.setVisible(true);
                update.setVisible(false);
                delete.setVisible(false);
                addNewNews.setVisible(false);
            }
        });

        actionToolStrip.addButton(addNewNews);
        actionToolStrip.addButton(add);
        actionToolStrip.addSeparator();
        actionToolStrip.addButton(update);
        actionToolStrip.addButton(delete);
        actionToolStrip.setHeight(30);

        navigationLayout.addMember(actionToolStrip);
        navigationLayout.setHeight(30);

        wrapperLayout.addMember(navigationLayout);

        listGrid = new ListGrid() {

            @Override
            protected Canvas createRecordComponent(final ListGridRecord record, Integer colNum) {

                if (colNum == 0) {

                    HLayout recordCanvas = new HLayout(3);
                    recordCanvas.setHeight(22);
                    recordCanvas.setAlign(Alignment.CENTER);
                    recordCanvas.addClickHandler(new ClickHandler() {
                        public void onClick(ClickEvent event) {
                            updateNewsInfo(record);
                        }
                    });

                    Img img1 = new Img(record.getAttribute("url"), 99, 99);
                    recordCanvas.addMember(img1);
                    Canvas recordCanvas1 = new Canvas();
                    recordCanvas1.setContents(record.getAttribute("name"));
                    recordCanvas1.setWidth(170);

                    recordCanvas.addMember(recordCanvas1);
                    return recordCanvas;
                }

                return null;
            }
        };
        listGrid.setWidth(300);
        listGrid.setShowHeader(false);
        listGrid.setCellHeight(100);
        listGrid.setShowRecordComponents(true);
        listGrid.setShowRecordComponentsByCell(true);

        listGrid.addRecordClickHandler(new RecordClickHandler() {
            public void onRecordClick(RecordClickEvent event) {
                updateNewsInfo(event.getRecord());
            }
        });

        final NewsServiceAsync imageServiceAsync = GWT.create(NewsService.class);
        imageServiceAsync.getImages(new AsyncCallback<List<News>>() {
            public void onFailure(Throwable caught) {
                //To change body of implemented methods use File | Settings | File Templates.
            }

            public void onSuccess(List<News> result) {
                updateGrid(result);
            }
        });

        listGrid.setFields(new ListGridField("project"));

        newsUpdateLayout.addMember(listGrid);
        newsUpdateLayout.addMember(wrapperLayout);

        addMember(newsUpdateLayout);

        createNewsEditor(wrapperLayout);

        setWidth100();
        setHeight100();
    }

    private void selectFIrstRecord(RecordList recordList) {
        if (recordList.getLength() != 0) {
            final ListGridRecord firstRecord = (ListGridRecord) recordList.get(0);
            listGrid.selectRecord(firstRecord);
            updateNewsInfo(firstRecord);
        } else {
            addNewNews.setVisible(false);
            add.setVisible(true);
            delete.setVisible(false);
            update.setVisible(false);
        }
    }

    private void updateNewsInfo(ListGridRecord record) {
        newImage.setSrc(record.getAttribute("url"));
        title.setValue(record.getAttribute("name"));
        richTextEditor.setValue(record.getAttribute("text"));
        listGrid.deselectAllRecords();
        listGrid.selectRecord(record);
        addNewNews.setVisible(true);
        add.setVisible(false);
        delete.setVisible(true);
        update.setVisible(true);

        if (bufImage != null && !bufImage.isEmpty()) {
            final ImageServiceAsync imageServiceAsync = GWT.create(ImageService.class);
            imageServiceAsync.removeTempImage(bufImage, new AsyncCallback<Void>() {
                @Override
                public void onFailure(Throwable caught) {
                }

                @Override
                public void onSuccess(Void result) {
                    bufImage = null;
                }
            });
            bufImage = null;
        }
    }

    private void createNewsEditor(VLayout wrapperLayout) {
        HLayout editorWrapper = new HLayout();
        editorWrapper.setWidth100();
        editorWrapper.setHeight100();
        initComplete(this);

        VLayout imageHolder = new VLayout(5);
        imageHolder.setWidth(100);
        imageHolder.setHeight100();

        newImage = new Img(NO_PHOTO_NAME, 200, 200);
        imageHolder.addMember(newImage);

        IButton uploadBtn = new IButton("Upload");
        uploadBtn.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                final com.smartgwt.client.widgets.Window winModal = new com.smartgwt.client.widgets.Window();

                ValuesManager vm = new ValuesManager();
                final DynamicForm uploadForm = new DynamicForm();
                uploadForm.setValuesManager(vm);
                uploadForm.setEncoding(Encoding.MULTIPART);
                uploadForm.setTarget("fileUploadFrame");
                uploadForm.setAction(GWT.getModuleBaseURL() + "fileUploadServlet");
                uploadForm.setMethod(FormMethod.POST);

                List<FormItem> items = new ArrayList<FormItem>();

                final UploadItem fileItem = new UploadItem("image");
                fileItem.setShowTitle(false);
                fileItem.setAccept("image/gif,image/jpeg,image/pjpeg,image/png,image/vnd.wap.wbmp");
                items.add(fileItem);

                IButton uploadButton = new IButton("Upload");
                uploadButton.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent e) {
                        Object obj = fileItem.getDisplayValue();

                        if (obj != null) {
                            uploadForm.submitForm();
                            winModal.hide();
                        } else
                            SC.say("Please select a file.");
                    }
                });

                FormItem[] fitems = new FormItem[items.size()];
                items.toArray(fitems);
                uploadForm.setItems(fitems);

                winModal.addItem(uploadForm);
                winModal.addItem(uploadButton);
                winModal.setIsModal(true);
                winModal.centerInPage();
                winModal.setWidth(250);
                winModal.setHeight(100);

                winModal.show();

            }
        });
        IButton deleteBtn = new IButton("Remove");
        deleteBtn.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                newImage.setSrc(NO_PHOTO_NAME);
                bufImage = NO_PHOTO_NAME;
            }
        });

        imageHolder.addMember(uploadBtn);
        imageHolder.addMember(deleteBtn);

        Canvas iframe = new Canvas();
        iframe.setContents("<IFRAME NAME=\"fileUploadFrame\" style=\"width:0;height:0;border:0\"></IFRAME>");
        iframe.setVisibility(Visibility.VISIBLE);

        VLayout contentHolder = new VLayout();
        contentHolder.setWidth100();
        contentHolder.setHeight100();

        DynamicForm contentForm = new DynamicForm();
        contentForm.setWidth100();
        contentForm.setHeight100();
        contentForm.setTitleAlign(Alignment.LEFT);
        contentForm.setCellPadding(1);

        title = new TextItem("Title");
        title.setWidth("*");
        richTextEditor = new TextAreaItem();
        richTextEditor.setShowTitle(false);
        richTextEditor.setLength(5000);
        richTextEditor.setColSpan(2);
        richTextEditor.setWidth("*");
        richTextEditor.setHeight(469);

        add.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                final NewsServiceAsync imageServiceAsync = GWT.create(NewsService.class);
                imageServiceAsync.addNews(bufImage, title.getValueAsString(), richTextEditor.getValueAsString(), new AsyncCallback<List<News>>() {
                    public void onFailure(Throwable caught) {
                        //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public void onSuccess(List<News> result) {
                        updateGrid(result);
                    }
                });
            }
        });

        contentForm.setFields(title, richTextEditor);
        contentHolder.addMember(contentForm);

        editorWrapper.addMember(imageHolder);
        editorWrapper.addMember(contentHolder);
        imageHolder.addMember(iframe);

        wrapperLayout.addMember(editorWrapper);
    }

    private void updateGrid(List<News> result) {
        final RecordList recordList = new RecordList();
        if (result.size() == 0) {
            title.setValue("");
            richTextEditor.setValue("");
            newImage.setSrc(NO_PHOTO_NAME);
        }

        for (News news : result) {
            final ListGridRecord record = new ListGridRecord();
            record.setAttribute("url", news.getNewsImageUrlLittle());
            record.setAttribute("name", news.getNewsTitle());
            record.setAttribute("text", news.getNewsText());
            record.setAttribute("id", news.getId());

            recordList.add(record);
        }
        listGrid.setData(recordList);

        selectFIrstRecord(recordList);
    }

    private native void initComplete(NewsViewer upload)
    /*-{
        $wnd.uploadComplete = function (fileName) {
            upload.@com.smartum.mpr.client.view.NewsViewer::uploadComplete(Ljava/lang/String;)(fileName);
        };
    }-*/;

    public void uploadComplete(String fileName) {
        if (NO_PHOTO_NAME.equals(fileName)) {
            SC.say("Please upload acceptable image.");
        }

        if (bufImage != null && !bufImage.isEmpty()) {
            final ImageServiceAsync imageServiceAsync = GWT.create(ImageService.class);
            imageServiceAsync.removeTempImage(bufImage, new AsyncCallback<Void>() {
                public void onFailure(Throwable caught) {
                }

                public void onSuccess(Void result) {
                }
            });
        }
        bufImage = fileName;
        newImage.setSrc(fileName);
    }

    @Override
    public Canvas getNewsViewerWidget() {
        return this;
    }
}
